Author: Gavin DeBrun
import numpy as np
import matplotlib.pyplot as plt
from astropy import units as u
from astropy.coordinates import SkyCoord
from astroquery.mast import Tesscut
from glob import glob
import lightkurve as lk
from tess_stars2px import tess_stars2px_function_entry
import pandas as pd
from mpl_toolkits.axes_grid1 import make_axes_locatable
from IPython.display import HTML
from matplotlib import animation
import matplotlib
matplotlib.rcParams['animation.embed_limit'] = 2**128
pixelfile = lk.search_targetpixelfile("KIC 8462852", quarter=16).download()
pixelfile.plot(frame=1)
lc = pixelfile.to_lightcurve(aperture_mask='all')
lc.plot()
plt.show()
The target I chose is Epsilon Reticuli A (HD 27442 A). It's a subgiant 60 ly from earth with a radius of $3.18R_{\odot}$, a mass of $1.5M_{\odot}$, a luminosity of $6.2L_{\odot}$, and an apparent magnitude of $4.44$. It's confirmed to have at least one gas giant exoplanet (HD 27442 b), discovered in 2000 through the radial velocity method. It has a mass of 1.56 Jupiters, with an orbital period of 428 days at a distance of 1.27 AU. Epsilon Reticuli A also has a companion white dwarf (HD 27442 B), with an orbital period of about 2,700 years at a distance of 240 AU, or 13 arcseconds. This white dwarf has a mass of $0.6M_{\odot}$, a radius of $0.0132R_{\odot}$, and an apparent magnitude of $12.5$.
I chose this target because I've performed the radial velocity analysis in another course, and I wanted to investigate its light curves to see if we could identify the exoplanet through the transit method. Further, TESS has observed Epsilon Reticuli 56,529 times between 2018 and 2023, providing a plethora of data. Given the orbital period of 428 days, there have been 4 orbits in this time. If the orbital plane is parallel with our line of sight, we might be able to detect the transit by observing decreases in flux.
c = SkyCoord('04 16 28.933 -59 18 10.441', unit=(u.hourangle, u.deg))
ra, dec = c.ra.degree, c.dec.degree
outID, outEclipLong, outEclipLat, sectors, outCam, outCcd, outColPix, outRowPix, scinfo = tess_stars2px_function_entry(9999, ra, dec)
sectors = list(sectors)
cutout_size = [51, 51]
force_download = False
RAstr, DECstr = str("{0:.6f}".format(ra)), str("{0:.6f}".format(dec))
coord_str = RAstr + '_' + DECstr
coords = SkyCoord(ra, dec, unit="deg")
fits_files = np.sort(glob('./*' + coord_str + '*.fits'))
bad_sectors = []
if fits_files.shape[0] != len(sectors) or force_download is True:
for sector in sectors:
skip = False
for file in fits_files:
file_sector = int(file[8:12])
if sector == file_sector:
skip = True
if skip:
continue
print(f"Trying sector {sector}...")
try:
manifest = Tesscut.download_cutouts(coordinates=coords, size=cutout_size, sector=sector)
print('\n')
except Exception as e:
bad_sectors.append(sector)
print(e, "\n")
continue
fits_files = np.sort(glob('./*' + coord_str + '*.fits'))
for bad_sector in bad_sectors:
sectors.remove(bad_sector)
print(f"We have good data from sectors: {sectors}")
Trying sector 64... 400 Client Error: Bad Request for url: https://mast.stsci.edu/tesscut/api/v0.1/astrocut?ra=64.12055416666665&dec=-59.30290027777777&y=51&x=51&units=px§or=64 Trying sector 65... 400 Client Error: Bad Request for url: https://mast.stsci.edu/tesscut/api/v0.1/astrocut?ra=64.12055416666665&dec=-59.30290027777777&y=51&x=51&units=px§or=65 Trying sector 66... 400 Client Error: Bad Request for url: https://mast.stsci.edu/tesscut/api/v0.1/astrocut?ra=64.12055416666665&dec=-59.30290027777777&y=51&x=51&units=px§or=66 Trying sector 68... 400 Client Error: Bad Request for url: https://mast.stsci.edu/tesscut/api/v0.1/astrocut?ra=64.12055416666665&dec=-59.30290027777777&y=51&x=51&units=px§or=68 Trying sector 69... 400 Client Error: Bad Request for url: https://mast.stsci.edu/tesscut/api/v0.1/astrocut?ra=64.12055416666665&dec=-59.30290027777777&y=51&x=51&units=px§or=69 We have good data from sectors: [2, 3, 4, 5, 8, 12, 28, 29, 30, 31, 32, 35, 38, 39, 62, 63]
target_pixel_files = []
for i in range(len(fits_files)):
try:
target_pixel_files.append(lk.read(fits_files[i]))
except Exception as e:
print(e, "\n")
continue
fig, ax = plt.subplots()
times = []
images = []
artists = []
i = 0
for tpf in target_pixel_files:
curr_times = tpf.time.to_datetime()
times.append(curr_times)
fluxes = tpf.hdu[1].data['FLUX'][tpf.quality_mask]
for j, flux in enumerate(fluxes):
if i % 100 == 0:
img = ax.imshow(flux, norm = 'log', vmin = 10, vmax = np.max(flux))
text = ax.annotate(f"{curr_times[j]}", (0,50))
plt.close()
images.append(img)
artists.append([img, text])
i += 1
times = np.concatenate(times).ravel()
print(f"Dates range from {times[0]} to {times[-1]} with {len(times)} observations")
assert np.array_equal(np.sort(times), times) # times are alredy sorted, so we can just stack the images to generate an animation
ax_divider = make_axes_locatable(ax)
cax = ax_divider.append_axes('right', size = '7%', pad='2%', label = 'flux')
cb = fig.colorbar(img, cax=cax)
cb.set_label(r"Flux $(e^{-}s^{-1})$", rotation = 270, labelpad=20, size=12)
ax.set_title("Flux of Epsilon Reticuli A for all Sectors")
ax.set_ylabel("Pixel Row Number")
ax.set_xlabel("Pixel Column Number")
ani = animation.ArtistAnimation(fig, artists, interval=25, blit=True)
HTML(ani.to_jshtml())
Dates range from 2018-08-23 15:16:30.515862 to 2023-04-06 09:30:08.184360 with 56529 observations